package cn.enilu.flash.utils.lottery;

import cn.enilu.flash.bean.core.BussinessLog;
import cn.enilu.flash.utils.lottery.entity.Gift;
import cn.hutool.core.math.MathUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.Range;

import java.util.*;

/**
 * @author HYF
 * @ClassName LotteryUtil
 * @date 2022年05月07日 2:54 下午
 */
@Slf4j
public class LotteryUtil {

    //概率总数
    private final static Long AMOUNT_ODDS = 100L;
    //倍率
    private final static Integer MULTIPLE = 1;
    //盐值
    private final static String SALT = "857fa29b959413c600cd575d61b36602c1d70cc7293ba8fa295006663e26537f";
    //初始块
    private final static String INITIAL_BLOCK = "0000000000000000";


    /**
     * 区间获取礼品
     *
     * @return
     */
    public static List<Gift> getRangeGift(List<Gift> giftList, Integer times) {
        Long odds = 0L;
        for (Gift gift : giftList) {
            odds += gift.getOdds();
        }
        if (odds <= 0 || odds > 100) {
            log.error("当前概率异常-总概率小于等于0或者大于100");
            throw new RuntimeException("总概率小于等于0或者大于100");

        }
        if (odds > 0 && odds < 100) {
//            Gift emptyGift = new Gift(null, 100 - odds);
//            giftList.add(emptyGift);
            log.error("当前概率异常-总概率不等于100");
            throw new RuntimeException("总概率不等于100");
        }
        giftList.sort(Comparator.comparingLong(Gift::getOdds));
        Map<Range<Long>, Gift> rangeGiftMap = new HashMap<>();

        Long beforeOdds = 0L;
        for (int i = 0; i < giftList.size(); i++) {
            Gift gift = giftList.get(i);
            Long nextOdds = beforeOdds + gift.getOdds();
            Range<Long> range = Range.between(beforeOdds, nextOdds);
            log.debug("当前区间={}", range);
            rangeGiftMap.put(range, gift);
            beforeOdds = nextOdds;
        }
        List<Gift> ret = new ArrayList<>();
        for (int i = 0; i < times; i++) {
            Long randomLong = RandomUtil.randomLong(AMOUNT_ODDS);
            log.debug("当前随机数={}", randomLong);
            ret.add(getGift(randomLong, rangeGiftMap));
        }

        return ret;
    }

    /**
     * 获取礼品
     *
     * @param randomLong
     * @param rangeGiftMap
     * @return
     */
    public static Gift getGift(Long randomLong, Map<Range<Long>, Gift> rangeGiftMap) {
        for (Map.Entry<Range<Long>, Gift> rangeGiftEntry : rangeGiftMap.entrySet()) {
            if (rangeGiftEntry.getKey().contains(randomLong)) {
                return rangeGiftEntry.getValue();
            }
        }
        return new Gift();
    }

    /**
     * 区间获取礼品
     *
     * @return
     */
    public static List<Gift> getRangeGift(List<Gift> giftList) {
        return getRangeGift(giftList, 1);
    }

    private static Digester digester = new Digester(DigestAlgorithm.SHA512);

    /**
     * 获取Hash礼品
     *
     * @return
     */
    public static Gift getHashGift(List<Gift> giftList) {
        Long odds = 0L;
        for (Gift gift : giftList) {
            odds += gift.getOdds();
        }
        if (odds <= 0 || odds > 100) {
            log.error("当前概率异常-总概率小于等于0或者大于100");
            throw new RuntimeException("总概率小于等于0或者大于100");

        }
        if (odds > 0 && odds < 100) {
//            Gift emptyGift = new Gift(null, 100 - odds);
//            giftList.add(emptyGift);
            log.error("当前概率异常-总概率不等于100");
            throw new RuntimeException("总概率不等于100");
        }
        giftList.sort(Comparator.comparingLong(Gift::getOdds));
        Map<Long, Gift> giftMap = new HashMap<>();
        Long key = 0L;
        Gift preGift = null;
        String preBlockHash = INITIAL_BLOCK;
        for (int j = 0; j < giftList.size(); j++) {
            Gift gift = giftList.get(j);

            Long currentOdds = gift.getOdds() * MULTIPLE;
            for (int k = 0; k < currentOdds; k++) {
                if (key != 0) {
                    preBlockHash = preGift.getHashCode();
                }
                String data = preBlockHash + "&" + gift.getName() + "&" + key + "&" + SALT;
                String digestHex = digester.digestHex(data);
                //实体转换 内存新建地址
                Gift giftChange = new Gift();
                giftChange.setFlag(false);
                giftChange.setHashCode(digestHex);
                giftChange.setId(gift.getId());
                giftChange.setName(gift.getName());
                giftChange.setOdds(gift.getOdds());
                giftMap.put(Long.valueOf(key), giftChange);
                preGift = gift;
                key++;
            }
        }
        Long randomLong = RandomUtil.randomLong(AMOUNT_ODDS * MULTIPLE);
        log.debug("当前随机数={}", randomLong);
        return giftMap.get(randomLong);
    }

    public static void main(String[] args) {
        Gift gift3 = new Gift("手机3", 30L, false);
        Gift gift1 = new Gift("手机1", 10L, false);
        Gift gift4 = new Gift("手机4", 40L, false);
        Gift gift2 = new Gift("手机2", 20L, false);
        List<Gift> list = new ArrayList<>();
        list.add(gift1);
        list.add(gift2);
        list.add(gift3);
        list.add(gift4);

//        log.info("Gift={}",getRangeGift(list));
        log.info("Gift={}", getHashGift(list));
        String a = "860377c4fe7c5527327dc57581b00eb98849d9bd725a9f09b8bbfe6cf6b381ac01383ec3182f42e219b6860d29ece015f619a835bf7a1711555bd1bb22255f87";
        System.out.println(a.length());
    }
}